#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include "HexDump.h"
#include "Resource.h"
#include "MainWnd.h"
#include "FileDialogs.h"

LRESULT CALLBACK MainWndProc(HWND wnd,
							 UINT msg,
							 WPARAM wParam,
							 LPARAM lParam)
{
	HDC            hdc;
	PAINTSTRUCT    ps;
	RECT           rect;
	RECT           rect2;
	HMENU          menu;
	TCHAR*         filename;
	static TEXTMETRIC  tm ;

	unsigned int cols, rows, x, y;
	static unsigned int charW, charH, capCharW, fileSize;

	static unsigned char byte;
	static char    buff[4];

	static TCHAR*  textExts [] = { TEXT("txt"), TEXT("ascii"), NULL };
	static TCHAR   textCat  [] = TEXT("Text");

	static TCHAR*  anyExt   [] = { TEXT("*"), NULL };
	static TCHAR   anyCat   [] = TEXT("Any");

	static FILE*   file = NULL;

	switch (msg)
	{
	case WM_CREATE:
		hdc = GetDC(wnd);

		GetTextMetrics(hdc, &tm);
		charW    = tm.tmAveCharWidth;
		capCharW = (tm.tmPitchAndFamily & 1 ? 3 : 2) * charW / 2;
		charH    = tm.tmHeight + tm.tmExternalLeading;

		ReleaseDC(wnd, hdc);
		return 0;

	case WM_COMMAND:
		menu = GetMenu(wnd);

		switch(LOWORD(wParam))
		{
		case IDM_OPEN:
			OpenFileDlg(&filename, anyCat, anyExt, NULL);
			if (file)
				fclose(file);
#ifdef UNICODE
			file = _wfopen(filename, L"rb");
#else
			file = fopen(filename, "rb");
#endif
			// Get file size
			fseek(file, 0, SEEK_END);
			fileSize = ftell(file);
			rewind(file);

			free(filename);
			SendMessage(wnd, WM_PAINT, (WPARAM)NULL, (LPARAM)NULL);
			return 0;

		case IDM_SAVE_TEXTFILE:
			SaveFileDlg(&filename, textCat, textExts, NULL);
			free(filename);
			return 0;

		case IDM_SAVE_BINARYFILE:
			SaveFileDlg(&filename, anyCat, anyExt, NULL);
			free(filename);
			return 0;

		case IDM_EXIT:
			SendMessage(wnd, WM_CLOSE, 0, 0);
			return 0;

		case IDM_HELP:
			MessageBox(wnd, TEXT("Help not yet implemented!"),
				NULL, MB_ICONEXCLAMATION | MB_OK);
			return 0;

		case IDM_ABOUT:
			MessageBox(wnd, TEXT("Hex Dump\n") TEXT("Anthony Eden"),
				TEXT("Hex Dump"), MB_ICONINFORMATION | MB_OK);
			return 0;
		}
		break;

	case WM_PAINT:
		hdc = BeginPaint(wnd, &ps);

		if (!file)
			goto EndOfPainting;

		GetClientRect(wnd, &rect);

		rows = rect.bottom / charH;
		cols = rect.right  / (charW * 3);

		rewind(file);
		for (y = 0; y < rows; ++y)
		{
			for (x = 0; x < cols; ++x)
			{
				if (ftell(file) == fileSize)
					goto EndOfPainting;

				fread(&byte, 1, 1, file);
				sprintf(buff, "%02x", byte);

				rect2.left   = x * (charW * 3);
				rect2.right  = rect2.left + (charW * 3);
				rect2.top    = y * charH;
				rect2.bottom = rect2.top + charH;
				DrawTextA(hdc, buff, 2, &rect2, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
			}
		}

EndOfPainting:
		EndPaint(wnd, &ps);
		return 0;

	case WM_DESTROY:
		if (file)
			fclose(file);
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(wnd, msg, wParam, lParam);
}
